home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / DBglxwidget / overlay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.2 KB  |  422 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * overlay.c
  19.  *   Test routine for working with glxDraw widgets.
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <errno.h>
  24.  
  25. #include <X11/Xlib.h>
  26. #include <X11/StringDefs.h>
  27. #include <X11/Intrinsic.h>
  28. #include <X11/keysym.h>
  29.  
  30. #include <Xm/Xm.h>
  31. #include <Xm/Frame.h>
  32.  
  33. #include "GlxMDraw.h"
  34.  
  35.  
  36. int   oldx, oldy, curx, cury, dx, dy;
  37. #ifdef USE_NEW_WIDGET
  38. enum { SINGLE, DOUBLE } bufferMode;
  39. #endif
  40.  
  41. /* The GLX configuration parameter:
  42.  *     Double buffering
  43.  *    color index (default so unspecified)
  44.  *    overlay
  45.  *    nothing else special
  46.  */
  47.  
  48. #define OV_TYPE        2
  49.  
  50. static GLXconfig glxConfig [] = {
  51.     { GLX_NORMAL, GLX_DOUBLE, FALSE },
  52.     { GLX_NORMAL, GLX_BUFSIZE, GLX_NOCONFIG },
  53.     { GLX_OVERLAY, GLX_BUFSIZE, 2 },
  54.     { 0, 0, 0 }
  55. };
  56.  
  57. String fallback_resources[] = {
  58.     "*geometry: =750x600",
  59.     "*frame*shadowType: SHADOW_IN",
  60.     NULL
  61. };
  62.  
  63. Boolean use_pups=FALSE;    /* if TRUE, must use popup planes */
  64.  
  65. static XtAppContext app_context;
  66.  
  67. /* forward declarations of callbacks */
  68. static void exposeCB();
  69. static void overlayExposeCB();
  70. static void resizeCB();
  71. static void initCB();
  72. static void inputCB();
  73.  
  74. main (int argc, char *argv[])
  75. {
  76.     Arg            args[20];
  77.     int            n = 0;
  78.     Widget        toplevel, frame, glw;
  79.     Window        windows[3];
  80.  
  81.     /*----
  82.      * First, initialize the display.
  83.      *----*/
  84.  
  85.     toplevel = XtAppInitialize(&app_context, "4DgiftsGlx", 
  86.                    (XrmOptionDescList)NULL , 0,
  87. #if XtSpecificationRelease == 4
  88.                    (Cardinal*)&argc, 
  89. #else
  90.                    &argc, 
  91. #endif
  92.                    (String*)argv, 
  93.                    fallback_resources,
  94.                    (ArgList)NULL, 0);
  95.  
  96.     /*----
  97.      * Find out if we can use overlay planes (they exist),
  98.      * otherwise, use popup planes.  While we're at it,
  99.      * fix the glxConfig parameter to request popup planes
  100.      * instead of the default overlay planes (default because
  101.      * we defined it above).
  102.      *----*/
  103.  
  104.     if (getgdesc(GD_BITS_OVER_SNG_CMODE) < 2)
  105.     {
  106.     use_pups = TRUE;
  107.     glxConfig[OV_TYPE].buffer = GLX_POPUP;
  108.     }
  109.  
  110.     /*----
  111.      * Create a frame widget to put the GLX widget into.
  112.      *----*/
  113.  
  114.     n = 0;
  115.     frame = XtCreateManagedWidget("frame",
  116.                   xmFrameWidgetClass,
  117.                   toplevel, args, n);
  118.  
  119.     /*----
  120.      * Set up the resources/arguments for the GLX widget and
  121.      * then create the widget.
  122.      *----*/
  123.  
  124.     n = 0;
  125.     XtSetArg(args[n], GlxNglxConfig, glxConfig); n++;
  126.     XtSetArg(args[n], use_pups?GlxNusePopup:GlxNuseOverlay, TRUE); n++;
  127. #ifdef USE_NEW_WIDGET
  128.     XtSetArg(args[n], GlxNprovideSingleBuffer, TRUE); n++;
  129. #endif
  130.     glw = XtCreateManagedWidget("glwidget",
  131.                   glxMDrawWidgetClass,
  132.                   frame, args, n);
  133.  
  134. #ifdef USE_NEW_WIDGET
  135.     /*----
  136.      * This is just a flag to help me keep track of which window
  137.      * is up now.
  138.      *----*/
  139.  
  140.     bufferMode = SINGLE;
  141. #endif
  142.  
  143.     /*----
  144.      * Add required callbacks.
  145.      *----*/
  146.  
  147.     XtAddCallback(glw, GlxNexposeCallback, exposeCB, 0);
  148.     XtAddCallback(glw,
  149.           use_pups?GlxNpopupExposeCallback:GlxNoverlayExposeCallback,
  150.           overlayExposeCB, 0);
  151.     XtAddCallback(glw, GlxNresizeCallback, resizeCB, 0);
  152.     XtAddCallback(glw, GlxNginitCallback, initCB, 0);
  153.     XtAddCallback(glw, GlxNinputCallback, inputCB, 0);
  154.  
  155.     /*----
  156.      * Ok, now we can realize our widgets.
  157.      *----*/
  158.  
  159.     XtRealizeWidget(toplevel);
  160.  
  161.     /*----
  162.      * Notify the window manager of colormaps that we are using
  163.      * so it will switch them in for us automatically.
  164.      *----*/
  165.  
  166.     XtVaGetValues (glw,
  167.            use_pups ? GlxNpopupWindow : GlxNoverlayWindow,
  168.            &windows[0], NULL);
  169.     windows[1] = XtWindow (glw);
  170.     windows[2] = XtWindow (toplevel);
  171.     XSetWMColormapWindows (XtDisplay (toplevel), XtWindow (toplevel),
  172.                windows, 3);
  173.  
  174.     XtAppMainLoop(app_context);
  175.  
  176. }
  177.  
  178. /* Return the overlay window of the widget */
  179. Window overlayWindow(w)
  180. Widget w;
  181. {
  182.     Arg args[1];
  183.     Window overlayWindow;
  184.  
  185.     XtSetArg(args[0], use_pups?GlxNpopupWindow:GlxNoverlayWindow,
  186.          &overlayWindow);
  187.     XtGetValues(w, args, 1);
  188.     return (overlayWindow);
  189. }
  190.  
  191. /* Callbacks */
  192. static void
  193. exposeCB(w, client_data, call_data)
  194.     Widget w;
  195.     caddr_t client_data;
  196.     GlxDrawCallbackStruct *call_data;
  197. {
  198.     GLXwinset(XtDisplay(w), call_data->window);
  199.     drawscene (dx, dy);
  200.     swapbuffers ();
  201. }
  202.  
  203. static void
  204. overlayExposeCB(w, client_data, call_data)
  205.     Widget w;
  206.     caddr_t client_data;
  207.     GlxDrawCallbackStruct *call_data;
  208. {
  209.     GLXwinset(XtDisplay(w), call_data->window);
  210.     drawhouse();
  211. }
  212.  
  213. static void
  214. resizeCB(w, client_data, call_data)
  215.     Widget w;
  216.     caddr_t client_data;
  217.     GlxDrawCallbackStruct *call_data;
  218. {
  219.     GLXwinset(XtDisplay(w), call_data->window);
  220.     viewport(0, (Screencoord) call_data->width-1,
  221.          0, (Screencoord) call_data->height-1);
  222.     drawscene(dx,dy);
  223.     GLXwinset(XtDisplay(w), overlayWindow(w));
  224.     viewport(0, (Screencoord) call_data->width-1,
  225.          0, (Screencoord) call_data->height-1);
  226.     drawhouse();
  227. }
  228.  
  229. static void
  230. initCB(w, client_data, call_data)
  231.     Widget w;
  232.     caddr_t client_data;
  233.     GlxDrawCallbackStruct *call_data;
  234. {
  235.     GLXwinset(XtDisplay(w), call_data->window);
  236.     initialize_gl();
  237.     dx = call_data->width / 2;
  238.     dy = call_data->height / 2;
  239.     GLXwinset(XtDisplay(w), overlayWindow(w));
  240.     initialize_overlay();
  241. }
  242.  
  243. static void
  244. inputCB(w, client_data, call_data)
  245.     Widget w;
  246.     caddr_t client_data;
  247.     GlxDrawCallbackStruct *call_data;
  248. {
  249.     char buffer[1];
  250.     KeySym keysym;
  251.     static Position oldx, oldy, newx, newy;
  252.     static Boolean buttonDown = FALSE;
  253.  
  254.     GLXwinset(XtDisplay(w), call_data->window);
  255.     switch(call_data->event->type)
  256.     {
  257.     case KeyRelease:
  258.     /* It is necessary to convert the keycode to a keysym before
  259.      * it is possible to check if it is an escape
  260.      */
  261.     if (XLookupString((XKeyEvent *)call_data->event,
  262.                       buffer,1,&keysym,NULL) == 1 &&
  263.         keysym == (KeySym)XK_Escape)
  264.         exit(0);
  265.     break;
  266.     case ButtonPress:
  267.     switch(call_data->event->xbutton.button)
  268.     {
  269.     case Button1:
  270.         buttonDown = TRUE;
  271.         oldx = newx = call_data->event->xbutton.x;
  272.         oldy = newy = call_data->event->xbutton.y;
  273.         break;
  274. #ifdef USE_NEW_WIDGET
  275.       case Button2:
  276.         XtVaSetValues (w, GlxNsingleBuffer, TRUE, NULL);
  277.         bufferMode = SINGLE;
  278.         drawscene (dx, dy);
  279.         if (bufferMode == DOUBLE)
  280.         swapbuffers ();
  281.         break;
  282.  
  283.       case Button3:
  284.         XtVaSetValues (w, GlxNsingleBuffer, FALSE, NULL);
  285.         bufferMode = DOUBLE;
  286.         drawscene (dx, dy);
  287.         if (bufferMode == DOUBLE)
  288.         swapbuffers ();
  289.         break;
  290. #endif
  291.     }
  292.     break;
  293.     case ButtonRelease:
  294.     switch(call_data->event->xbutton.button)
  295.     {
  296.     case Button1:
  297.         buttonDown = FALSE;;
  298.         break;
  299.     }
  300.     break;
  301.     case MotionNotify:
  302.     if (buttonDown && call_data->event->xmotion.state & Button1Mask)
  303.     {
  304.         oldx = newx;
  305.         oldy = newy;
  306.         newx = call_data->event->xbutton.x;
  307.         newy = call_data->event->xbutton.y;
  308.         dx += newx-oldx;
  309.         /* GL and X have opposite y coordinates so subtract from dy */
  310.         dy -= newy-oldy;
  311.         drawscene (dx, dy);
  312. #ifdef USE_NEW_WIDGET
  313.         if (bufferMode == DOUBLE)
  314. #endif
  315.         swapbuffers ();
  316.     }
  317.     break;
  318.     }
  319. }
  320.  
  321. initialize_gl () {
  322.     long xmaxscrn, ymaxscrn;     /* maximum size of screen in x and y       */
  323.     long xscrnsize;              /* size of screen in x used to set globals */
  324.     Colorindex dummy;            /* for strict ANSI C prototyping           */
  325.  
  326.     xscrnsize = getgdesc(GD_XPMAX);       /* get/set screen size[/aspect] */
  327.     if (xscrnsize == 1280) {
  328.          xmaxscrn = 1279;
  329.          ymaxscrn = 1023;
  330.          keepaspect(5, 4);
  331.     } else if (xscrnsize == 1024) {
  332.          xmaxscrn = 1023;
  333.          ymaxscrn = 767;
  334.          keepaspect(4, 3);
  335.     } else {
  336.         fprintf(stderr, "Something's EXTREMELY wrong:  ");
  337.         fprintf(stderr, "xscrnsize=%d\n", xscrnsize);
  338.         exit(-1) ;
  339.     }
  340.     doublebuffer ();
  341.     shademodel (FLAT);
  342. }
  343.  
  344. initialize_overlay()
  345. {
  346.     mapcolor (1, 255, 0, 255);
  347.     mapcolor (2, 0, 255, 255);
  348. }
  349.  
  350. /*  Everytime through the loop, draw only the car, not the house.  */
  351. drawscene (x, y)
  352. int     x, y;
  353. {
  354.     color (BLACK);
  355.     clear ();
  356.     drawcar (x, y);
  357.     gflush();
  358. }
  359.  
  360. /*  draw a car with several colors.
  361.  *  The car itself is drawn with  the front window first.  Then the front
  362.  *  window is flipped over (scaled) for the  rear  window.  The translate
  363.  *  routine moves the car to an (x,y) position.
  364.  */
  365. drawcar (x, y)
  366. int     x, y;
  367. {
  368.     float   fx, fy;
  369.  
  370.     fx = (float) x;
  371.     fy = (float) y;
  372.     pushmatrix ();
  373.     translate (fx, fy, 0.0);        /*  move to mouse location  */
  374.     color (BLUE);                   /*  wheels  */
  375.     circfi (-75, -75, 20);
  376.     circfi (75, -75, 20);
  377.     color (RED);                    /*  car body  */
  378.     pmv2i (-150, -50);
  379.     pdr2i (-125, 0);
  380.     pdr2i (125, 0);
  381.     pdr2i (150, -50);
  382.     pclos ();
  383.     color (YELLOW);                 /*  front window  */
  384.     drawwindow ();
  385.     color (GREEN);                  /*  rear window  */
  386.     scale (-1.0, 1.0, 1.0);
  387.     drawwindow ();
  388.     popmatrix ();
  389. }
  390.  
  391. /*  draw a window for the car  */
  392. drawwindow () {
  393.     pmv2i (0, 0);
  394.     pdr2i (0, 50);
  395.     pdr2i (50, 50);
  396.     pdr2i (75, 0);
  397.     pclos ();
  398. }
  399.  
  400. /*  draw a house in two colors at a fixed position, specified by the trans-
  401.  *  late routine.  The house is drawn with colors in the 4D overlay bitplanes.
  402.  */
  403. drawhouse () {
  404.     color (0);
  405.     clear ();
  406.     pushmatrix ();
  407.     translate (200.0, 100.0, 0.0);     /*  move house into position  */
  408.     color (1);                         /*  roof   */
  409.     pmv2i (0, 0);
  410.     pdr2i (0, 250);
  411.     pdr2i (350, 250);
  412.     pdr2i (350, 0);
  413.     pclos ();
  414.     color (2);                         /*  1st floor  */
  415.     pmv2i (175, 400);
  416.     pdr2i (0, 250);
  417.     pdr2i (350, 250);
  418.     pclos ();
  419.     popmatrix ();
  420.     gflush();
  421. }
  422.